package bag

import (
	"encoding/json"
	"sanguo/node/common/DropPool"
	"sanguo/node/common/com_type"
	table_DropPool "sanguo/node/table/excel/table/DropPool"
	table_Item "sanguo/node/table/excel/table/Item"
	cs_message "sanguo/protocol/cs/message"

	"github.com/golang/protobuf/proto"
)

type ItemEventReceiver interface {
	OnAwardByItem(*DropPool.Award)
	//OnItemCellDirty()
}

//道具
type Item struct {
	ItemId       int32
	ItemCount    int32
	ItemUseTimes int32 //当前道具使用次数
}

type RoleItem struct {
	itemList  map[int32]*Item
	itemDirty map[int32]bool
	dbDirty   bool
	receiver  ItemEventReceiver
}

func FuncNewItem(itemId int32, itemCount int32) *Item {
	return newItem(itemId, itemCount)
}

func newItem(itemId int32, itemCount int32) *Item {
	itemDef := table_Item.Table_.IDMap[itemId]

	item := &Item{
		ItemId:       itemDef.ID,
		ItemCount:    itemCount,
		ItemUseTimes: int32(0),
	}
	return item
}

func (this *Item) GetItemId() int32 {
	return this.ItemId
}

func (this *RoleItem) GetItem(itemId int32) *Item {
	return this.itemList[itemId]
}

func (this *RoleItem) RefreshItemUseTimes() {
	for _, v := range this.itemList {
		if v.ItemUseTimes != 0 {
			v.ItemUseTimes = 0
			this.itemDirty[v.ItemId] = true
		}
	}
	this.dbDirty = true
}

//增加道具
func (this *RoleItem) AddItem(itemId int32, count int32) {
	itemDef := table_Item.Table_.IDMap[itemId]
	if itemDef == nil {
		return
	}

	item := this.GetItem(itemId)
	if item != nil {
		item.ItemCount += count
	} else {
		this.itemList[itemId] = newItem(itemId, count)
	}

	this.dbDirty = true
	this.itemDirty[itemId] = true
}

//使用道具
func (this *RoleItem) UseItem(itemID, count int32) bool {
	//读表 查询道具使用等级 时间
	itemDef := table_Item.Table_.IDMap[itemID]
	if itemDef == nil {
		return false
	}

	item := this.GetItem(itemID)
	if item == nil {
		return false
	}

	if item.ItemCount < count {
		return false
	}

	item.ItemCount -= count
	if itemDef.Limit != 0 {
		item.ItemUseTimes += count
	}

	if itemDef.Type == com_type.Item_Gift { //使用的为礼包
		this.AwardByUseItem(item.ItemId, count)
	}

	this.dbDirty = true
	this.itemDirty[itemID] = true
	return true

}

//获取道具列表
func (this *RoleItem) GetItemList() map[int32]*Item {
	return this.itemList
}

/****************** 奖励计算 *****************/

//礼包处理
func (this *RoleItem) AwardByUseItem(itemId, count int32) {
	//读表
	DropPoolID := table_Item.Table_.IDMap[itemId].DropPool
	DropDef := table_DropPool.Table_.IDMap[DropPoolID]
	if DropDef == nil {
		return
	}
	awards := []*DropPool.Award{}
	for i := int32(0); i < count; i++ {
		awards = append(awards, DropPool.InitAward(DropPoolID))
	}
	this.receiver.OnAwardByItem(DropPool.PackAwardsToOne(awards))
}

//打包道具格子
func (this *RoleItem) PackAllItem() []*cs_message.Item {
	var items = make([]*cs_message.Item, 0)
	for _, v := range this.itemList {
		if v.ItemCount != 0 {
			item := &cs_message.Item{
				ItemId:       proto.Int32(v.ItemId),
				ItemCount:    proto.Int32(v.ItemCount),
				ItemUseTimes: proto.Int32(v.ItemUseTimes),
			}
			items = append(items, item)
		}
	}

	return items
}

func (this *RoleItem) GetItemDirtyLength() int {
	return len(this.itemDirty)
}

func (this *RoleItem) PackItemModify() []*cs_message.Item {
	var items = make([]*cs_message.Item, 0)
	for id, b := range this.itemDirty {
		if b {
			delete(this.itemDirty, id)
			v := this.itemList[id]
			item := &cs_message.Item{
				ItemId:       proto.Int32(v.ItemId),
				ItemCount:    proto.Int32(v.ItemCount),
				ItemUseTimes: proto.Int32(v.ItemUseTimes),
			}
			items = append(items, item)

			/*
			*道具数量为0后 判断该道具是否有使用次数限制
			*是 则不删除，避免后面再次获取该道具，它的使用次数又重置为0
			*否 删除不影响道具
			* limit == 0 表示为无次数限制
			 */
			if v.ItemCount == 0 {
				itemDef := table_Item.Table_.IDMap[v.ItemId]
				if itemDef.Limit == 0 {
					delete(this.itemList, v.ItemId)
				}
			}
		}
	}
	return items

}

/****************************************/

func (this *RoleItem) PackJson(fields map[string]interface{}) {
	if this.dbDirty {
		jsonStr, err := json.Marshal(this.itemList)
		if nil == err {
			fields["item"] = jsonStr
		}
	}
}

func (this *RoleItem) IsDirty() bool {
	return this.dbDirty

}

func (this *RoleItem) SetDirtyFlag() {
	this.dbDirty = true
}

func (this *RoleItem) ClearDirtyFlag() {
	this.dbDirty = false
}

func (this *RoleItem) Init(receiver ItemEventReceiver, items map[int32]*Item) {
	this.itemList = items
	this.itemDirty = map[int32]bool{}
	this.receiver = receiver
	this.dbDirty = false

}
